package com.element.security.single.handler;

import com.common.core.constant.SecurityHeader;
import com.common.core.exception.code.SecurityErrorCode;
import com.common.core.results.SingleResult;
import com.common.core.results.VoidResult;
import com.common.core.utils.MDFiveUtil;
import com.element.security.single.constant.SecurityParams;
import com.element.security.single.model.AuthUserE;
import com.element.security.single.model.TokenCO;
import com.element.security.single.token.RedisTokenStore;
import com.element.security.single.utils.ResponseUtil;
import com.element.security.single.utils.SecurityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private RedisTokenStore redisTokenStore;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        logger.info("LoginSuccessHandler.onAuthenticationSuccess");
        AuthUserE authUser = SecurityUtil.getUser(authentication);
        if (null == authUser) {
            ResponseUtil.writeJson(response, VoidResult.failed(SecurityErrorCode.A_INSUFFICIENT_AUTHENTICATION_ERROR));
            return;
        }
        TokenCO tokenCO = new TokenCO();
        tokenCO.setTokenHeader(SecurityHeader.AUTH_SECURITY_HEADERS);
        tokenCO.setTokenType(SecurityHeader.AUTH_SECURITY_VALUE);
        long expires = authUser.getExpires();
        String accessToken = redisTokenStore.get(SecurityParams.getUserKey(authUser.getUserId()), String.class);
        if (!StringUtils.hasText(accessToken)) {
            accessToken = MDFiveUtil.getOnlyId();
            redisTokenStore.put(SecurityParams.getTokenKey(accessToken), authUser, expires);
            redisTokenStore.put(SecurityParams.getUserKey(authUser.getUserId()), accessToken, expires);
        } else {
            expires = redisTokenStore.getExpires(SecurityParams.getTokenKey(accessToken));
        }
        tokenCO.setAccessToken(accessToken);
        tokenCO.setExpiresIn(expires);
        ResponseUtil.writeJson(response, SingleResult.of(tokenCO));
    }
}